﻿#include "WRClass.h"
#include <QHash>
#include <QMutex>
#include <QMutexLocker>
#include "../WRConfig.h"

#include "../WRBasics.h"
#ifdef WRDEBUG
#include "WRException.h"
#endif

//表示类管理器。
class WRClassManager
{
private:
    //同步锁。
    QMutex m_mutex;
    //按标识索引表。
    QHash<QUuid, WRClass*> m_table1;
    //按名称索引表。
    QHash<QString, WRClass*> m_table2;

public:
    //初始化。
    inline WRClassManager(void)
    {
        //add code here
    }
    //释放资源。
    inline ~WRClassManager(void)
    {
        for(QHash<QUuid, WRClass*>::Iterator iter = m_table1.begin(); iter != m_table1.end(); ++iter)
        {
            WRClass* entry = iter.value();
            delete entry;
        }
    }

    //获取指定标识的类。
    inline WRClass* select(const QUuid& uuid)
    {
        QMutexLocker lock(&m_mutex);
        QHash<QUuid, WRClass*>::ConstIterator iter = m_table1.find(uuid);
        if (iter != m_table1.end())
        {
            return iter.value();
        }
        return 0;
    }
    //获取指定名称的类。
    inline WRClass* select(const QString& name)
    {
        QMutexLocker lock(&m_mutex);
        QHash<QString, WRClass*>::ConstIterator iter = m_table2.find(name);
        if (iter != m_table2.end())
        {
            return iter.value();
        }
        return 0;
    }
    //注册新的类。
    inline WRClass* enroll(const QUuid& uuid, const QString& name, WRClassActivator* init)
    {
        QMutexLocker lock(&m_mutex);
#ifdef WRDEBUG
        if (m_table1.contains(uuid))
        {
            throw WRArgumentException("uuid");
        }
        if (m_table2.contains(name))
        {
            throw WRArgumentException("name");
        }
#endif
        WRClass *entry = new WRClass(uuid, name, init);
        m_table1.insert(uuid, entry);
        m_table2.insert(name, entry);
        return entry;
    }

    //取消指定类信息。
    inline void cancel(const QUuid& uuid)
    {
        QMutexLocker lock(&m_mutex);
        QHash<QUuid, WRClass*>::ConstIterator iter = m_table1.find(uuid);
        if (iter != m_table1.end())
        {
            WRClass* entry = iter.value();
            m_table1.remove(entry->uuid());
            m_table2.remove(entry->name());
            delete entry;
        }
    }
};

namespace WR
{
    //获取类管理者实例。
    WRClassManager* classManager(void)
    {        
        static WRClassManager value;
        return &value;
    }
}

//获取指定标识的类信息。
WRClass* WRClass::select(const QUuid& uuid)
{
    WRClassManager* manager = WR::classManager();
    return manager->select(uuid);
}
//获取指定名称的类信息。
WRClass* WRClass::select(const QString& name)
{
    WRClassManager* manager = WR::classManager();
    return manager->select(name);
}
//获取指定配置的类信息。
WRClass* WRClass::select(const QDomElement& config)
{
    QString name = WRConfig::readClass(config);
    if (!name.isNull() && !name.isEmpty())
    {
        WRClassManager* manager = WR::classManager();
        return manager->select(name);
    }
    return 0;
}
//注册新的类信息。
WRClass* WRClass::enroll(const QUuid& uuid, const QString& name, WRClassActivator* init)
{
    WRClassManager* manager = WR::classManager();
    return manager->enroll(uuid, name, init);
}
